#pragma once

namespace cge {
	template
	<
		class Wrapped
	>
	class ListProxy{
	public:
		typedef typename Wrapped::iterator       WrappedIter;
		typedef typename Wrapped::const_iterator WrappedConstIter;
		typedef typename Wrapped::value_type     value_type;

		struct iterator {
			iterator() {}
			iterator( const iterator &rhs ):    i_(rhs.i_) {}
			iterator( const WrappedIter &rhs ): i_(rhs) {}

			iterator& operator++() { ++i_; return *this; }
			iterator& operator--() { --i_; return *this; }

			value_type& operator*()  { return *i_; }
			value_type& operator->() { return *i_; }

		private:
			WrappedIter i_;
		};

		struct const_iterator {
			const_iterator() {}
			const_iterator( const WrappedConstIter &rhs ): i_(rhs)    {}
			const_iterator( const WrappedIter &rhs ):      i_(rhs)    {}
			const_iterator( const const_iterator &rhs ):   i_(rhs.i_) {}
			const_iterator( const iterator &rhs ):         i_(rhs.i_) {}

			const_iterator& operator++() { ++i_; return *this; }
			const_iterator& operator--() { --i_; return *this; }

			const value_type& operator*()  { return *i_; }
			const value_type& operator->() { return *i_; }

		private:
			WrappedConstIter i_;
		};

		ListProxy( Wrapped &col ):   col_(col)     {}
		ListProxy( ListProxy&& lp ): col_(lp.col_) {}

		iterator       begin()       { return iterator(col_.begin()); }
		iterator       end()         { return iterator(col_.end()); }

		const_iterator begin() const { return const_iterator(col_.begin()); }
		const_iterator end()   const { return const_iterator(col_.end()); }

		bool           empty() const { return col_.empty(); }
		std::size_t    size()  const { return col_.size(); }

		const value_type& front() const { return col_.front(); }
		const value_type& back () const { return col_.back (); }
		value_type&       front()       { return col_.front(); }
		value_type&       back ()       { return col_.back(); }

	private:
		Wrapped& col_;
	};
}